package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.constant.Constants;
import cn.itsource.ymcc.constant.RConst;
import cn.itsource.ymcc.domain.Login;
import cn.itsource.ymcc.domain.User;
import cn.itsource.ymcc.mapper.UserMapper;
import cn.itsource.ymcc.openfeign.LoginOpenfeign;
import cn.itsource.ymcc.result.JsonResult;
import cn.itsource.ymcc.service.IUserService;
import cn.itsource.ymcc.util.AssertUtil;
import cn.itsource.ymcc.util.BitStatesUtils;
import cn.itsource.ymcc.vo.RegisterVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.Date;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author zongchangjiang
 * @since 2023-06-25
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private LoginOpenfeign loginOpenfeign;

    //事务   分布式事务问题
//    @Transactional
    @GlobalTransactional //seata 的分布式 事务 注解
    @Override
    public JsonResult register(RegisterVo registerVo) {
        String key = Constants.REGISTER_PHONE + registerVo.getMobile();
        if(!redisTemplate.hasKey(key)){
           return JsonResult.error("验证码已过期");
        }
        String smsCode = registerVo.getSmsCode();
        String value = redisTemplate.opsForValue().get(Constants.REGISTER_PHONE + registerVo.getMobile()).toString();
        AssertUtil.isTrue(value.equalsIgnoreCase(smsCode),"验证码输入错误");
        //去验证 手机号是否已经被注册了
        User phone = baseMapper.selectOne(new QueryWrapper<User>().eq("phone", registerVo.getMobile()));
        AssertUtil.isNull(phone,"该手机号已经注册了");
        //没有注册就直接保存数据
        User user = new User();
        user.setNickName(registerVo.getMobile());
        user.setCreateTime(new Date());
        user.setPhone(registerVo.getMobile());
        user.setSecLevel(RConst.Num.LONG_0);
        //位状态 ： 注册成功
        Long bitState = BitStatesUtils.addState(RConst.Num.LONG_0, BitStatesUtils.OP_REGISTED);
        System.out.println(Integer.toBinaryString(bitState.intValue()));
        //激活
        bitState = BitStatesUtils.addState(bitState, BitStatesUtils.OP_AUTHED_PHONE);
        System.out.println(Integer.toBinaryString(bitState.intValue()));
        user.setBitState(bitState);
        baseMapper.insert(user);



        //保存  uaa表
        Login login = new Login();
        //密码加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String password = bCryptPasswordEncoder.encode(registerVo.getPassword());
        login.setPassword(password);
        login.setUsername(registerVo.getMobile());
        login.setType(registerVo.getRegChannel());
        JsonResult jsonResult = loginOpenfeign.saveOrUpdate(login);
        Integer loginId = (Integer) jsonResult.getData(); //会出现转换异常 openFeign 会自动将Long转Integer
        //修改当前表
        user.setLoginId(loginId.longValue());
        baseMapper.updateById(user);

        int i = 1/0;

        return JsonResult.success();
    }
}
